import { Room } from '@/model/room/Room';
import { Movie } from '@/model/room/types';
import { Socket } from '@/model/socket/Socket';
import { useInjectable } from '@/unit/hooks/use-di';
import { errorMsg, warning } from '@/unit/message';
import Taro, { getEnv, useRouter } from '@tarojs/taro';
import { observer } from 'mobx-react-lite';
import React, {
  useCallback,
  useEffect,
  useState,
} from 'react';
import LiveAdmin from './live.admin.view';
import Live from './live.view';

// webSocket
export default observer(() => {
  const socket = useInjectable(Socket);
  const room = useInjectable(Room);
  // const login = useInjectable(Login);
  const env = getEnv();
  const router = useRouter();

  const [isOpened, setIsOpened] = useState<boolean>(false);
  const [isAdmin, setIsAdmin] = useState<boolean>(false);

  // 初始化
  useEffect(() => {
    const { roomid, isAdmin: _isAdmin } = router.params;
    if (!roomid) {
      warning('请刷新重试');
      return;
    }

    // 权限？
    setIsAdmin(_isAdmin === 'true' ? true : false);
    // 获取房间信息
    room.init(roomid).then(() => {
      // 获取房间电影列表
      room.getMovies().then(() => {
        // 初始链接
        room.setPlay(room.moviesList[0].url);
      });
    });

    console.log('直播页面初始化 --------------');
  }, [room, router, socket]);

  // 房主部分
  const handleOpen = useCallback(async () => {
    setIsOpened(true);

    await room.getMovies();
    //
  }, [room]);

  const handleClose = useCallback(() => {
    setIsOpened(false);
  }, []);

  const onUrlChange = useCallback(
    (value: string) => {
      room.setUrl(value);
    },
    [room]
  );

  const onPause = useCallback(() => {
    console.log('暂停');
    socket.sendMessage('player', {
      roomid: room.live.id,
      type: 'pause',
      content: '',
    });
  }, [room.live.id, socket]);

  const onPlay = useCallback(() => {
    // 点击播放链接以及地址发出
    console.log('play', room.roomliveinfo);
    socket.sendMessage('player', {
      roomid: room.live.id,
      type: 'play',
      content: room.roomliveinfo,
    });
  }, [room.live.id, room.roomliveinfo, socket]);

  const onEnded = useCallback(() => {
    console.log('onEnded');
    // 播放下一部
  }, []);

  const onError = useCallback((value: unknown) => {
    // 报错直接返回上一级完事
    errorMsg(String(value));
    // NavigateTo('home');
  }, []);

  const onReLoad = useCallback(() => {
    console.log('同步', room.roomliveinfo);
    socket.sendMessage('player', {
      roomid: room.live.id,
      type: 'reload',
      content: room.roomliveinfo,
    });
    Taro.createVideoContext(`${env}_video_admin`).pause();
  }, [env, room.live.id, room.roomliveinfo, socket]);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const onTimeUpdate = useCallback(
    // 两秒同步一次进度
    (e: CustomEvent) => {
      room.setDuration(e.detail.currentTime);
      socket.sendMessage('player', {
        roomid: room.live.id,
        type: 'current',
        content: e.detail.currentTime,
      });
    },
    [room, socket]
  );

  const handleDeleteMovie = useCallback(
    async (value: Movie) => {
      // console.log(value);
      await room.deleteMovie(value.id);
      await room.getMovies();
    },
    [room]
  );

  /**
   * 切换播放视频
   */
  const handlePlay = useCallback(
    (value: Movie) => {
      room.setPlay(value.url);
      socket.sendMessage('player', {
        roomid: room.live.id,
        type: 'play',
        content: room.roomliveinfo,
      });

      Taro.createVideoContext(`${env}_video_admin`).play();
    },
    [env, room, socket]
  );

  // 收看者 实验代码

  // 加入房间
  useEffect(() => {
    const { roomid } = router.params;

    if (!roomid) {
      warning('请刷新重试');
      return;
    }
    socket.sendMessage('join', {
      roomid: roomid,
    });
  }, [socket.sid, socket, router.params]);

  // 收听者身份

  useEffect(() => {
    if (!isAdmin && socket.sid !== '') {
      const videoContext = Taro.createVideoContext(`video`);

      const { event, data } = socket.message;
      // console.log(event, data);
      switch (event) {
        case 'play':
          room.setPlay((data as { url: string }).url);
          videoContext.play();
          break;
        case 'pause':
          videoContext.pause();
          break;
        case 'reload':
          room.setPlay((data as { url: string }).url);
          videoContext.seek(
            Number((data as { duration: string }).duration)
          );

          // 成功加载事件
          // socket.sendMessage('player', {
          //   roomid: room.live.id,
          //   type: 'reloadsucess',
          //   content: room.roomliveinfo,
          // });
          // videoContext.play();
          break;
        case 'current':
          const diff =
            Number(data) >
            Number(room.roomliveinfo.duration)
              ? Number(data) -
                Number(room.roomliveinfo.duration)
              : Number(room.roomliveinfo.duration) -
                Number(data);
          room.setOnlineDuration(data as string);
          if (diff > 3) {
            warning(`当前延时为${diff}秒`);
          }
          break;
        case 'newplayreload':
          // 新加入者同步
          room.setPlay((data as { url: string }).url);
          videoContext.seek(
            Number((data as { duration: string }).duration)
          );
          // seeked play
          break;
      }
    } else {
      const videoContext = Taro.createVideoContext(
        `${env}_video_admin`
      );

      const { event } = socket.message;
      switch (event) {
        case 'reloadsucess':
          videoContext.play();
          break;
        case 'newjoin':
          // 有新加入者派发当前视频地址和进度
          socket.sendMessage('player', {
            roomid: room.live.id,
            type: 'newplayreload',
            content: room.roomliveinfo,
          });
          break;
      }
    }
  }, [
    isAdmin,
    socket,
    socket.socket,
    socket.sid,
    socket.message,
    room,
    env,
  ]);

  const onTimeUpdateUser = useCallback(
    (e: CustomEvent) => {
      room.setDuration(e.detail.currentTime);
    },
    [room]
  );

  const onSeekComplete = useCallback(() => {
    socket.sendMessage('player', {
      roomid: room.live.id,
      type: 'reloadsucess',
      content: room.roomliveinfo,
    });
    Taro.createVideoContext(`video`).play();
  }, [room.live.id, room.roomliveinfo, socket]);

  const onReLoadAuto = useCallback(() => {
    // 用于差别较小时观看者主动同步
    const videoContext = Taro.createVideoContext(`video`);
    console.log('seek', room.onlineliveinfo);
    videoContext.seek(Number(room.onlineliveinfo.duration));
    // videoContext
  }, [room.onlineliveinfo]);

  return isAdmin ? (
    <LiveAdmin
      handleClose={handleClose}
      handleOpen={handleOpen}
      env={env}
      isOpened={isOpened}
      movies={room.movies}
      url={room.url}
      onUrlChange={onUrlChange}
      handleAdd={room.createMovie}
      playUrl={room.playUrl}
      onPause={onPause}
      onPlay={onPlay}
      onEnded={onEnded}
      onError={onError}
      onReLoad={onReLoad}
      onTimeUpdate={onTimeUpdate}
      handleDeleteMovie={handleDeleteMovie}
      handlePlay={handlePlay}
    />
  ) : (
    <Live
      playUrl={room.playUrl}
      onTimeUpdate={onTimeUpdateUser}
      env={env}
      onSeekComplete={onSeekComplete}
      onReLoad={onReLoadAuto}
    />
  );
});
